package com.huayi.datagovernance.config;

import cn.hutool.core.date.DateUnit;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.client.AsyncRestTemplate;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * RestTemplate配置
 * @author wuch
 * @version 1.0
 * @date 2021/4/1 11:07
 */
@Configuration
//@PropertySource("classpath:remoteservice.properties") 引入外部配置文件，进行属性注入
//@ConfigurationProperties(prefix = "mail")
public class RestTemplateConfig {


//    第三方服务地址
    /**
     * 数据代理
     */
    @Value("")
    public static String GIS_PROXY_OID;

    private final long Connect_Timeout =  DateUnit.MINUTE.getMillis()*3L;
    private final long Read_Timeout =  DateUnit.MINUTE.getMillis()*3L;

    /**
     * 线程池调度器
     * @return
     */
    @Bean("asyncTaskExecutor")
    public Executor asyncTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);//核心线程数
        executor.setMaxPoolSize(10);//最大线程数
        executor.setQueueCapacity(200);// 用来缓冲执行任务的队列
        executor.setKeepAliveSeconds(60);//允许线程的空闲时间，当超过了核心线程之外的线程，在空闲时间到达之后会被销毁
        executor.setThreadNamePrefix("异步任务线程调度-");//线程池名的前缀
        //这里采用CallerRunsPolicy策略，当线程池没有处理能力的时候，
        // 该策略会直接在execute方法的调用线程中运行被拒绝的任务；如果执行程序已关闭，则会丢弃该任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        // ConnectTimeout只有在网络正常的情况下才有效，因此两个一般都设置
//        factory.setConnectTimeout(1000*60*3);//建立连接的超时时间  3分钟
        factory.setConnectTimeout((int) Connect_Timeout);//建立连接的超时时间  3分钟
//        factory.setReadTimeout(1000*60*3);//传递数据的超时时间（在网络抖动的情况下，这个参数很有用） 3分钟
        factory.setReadTimeout((int) Read_Timeout);//传递数据的超时时间（在网络抖动的情况下，这个参数很有用） 3分钟
        return factory;
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate(clientHttpRequestFactory());
    }

    /**
     * AsyncRestTemplate 发起异步网络请求，由 Spring4.0 引入，
     * 但是在 5.0 就被表上了删除注解，官方推荐使用基于 React 的 WebClient 来代替。
     * @param asyncTaskExecutor
     * @return
     */
    @Bean
//    @DependsOn("asyncTaskExecutor")
    public AsyncRestTemplate asyncRestTemplate(ThreadPoolTaskExecutor asyncTaskExecutor) {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        //设置链接超时时间
        factory.setConnectTimeout((int) Connect_Timeout);
        //设置读取资料超时时间
        factory.setReadTimeout((int) Read_Timeout);
        //设置异步任务（线程不会重用，每次调用时都会重新启动一个新的线程）
        factory.setTaskExecutor(new SimpleAsyncTaskExecutor(asyncTaskExecutor));
        return new AsyncRestTemplate();
    }
}
